from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import json
import base64
import os
import requests
import urllib.parse

db = SQLAlchemy()

class Prompt(db.Model):
    __tablename__ = 'prompts'
    
    id = db.Column(db.Integer, primary_key=True)
    chrome_id = db.Column(db.String(50), unique=True, nullable=False, index=True)  # Chrome插件的ID
    text = db.Column(db.Text, nullable=False)
    image_data = db.Column(db.String(500), nullable=True)  # 缩略图文件路径
    original_image = db.Column(db.Text, nullable=True)  # 原图地址（URL或本地数据）
    image_url = db.Column(db.String(500), nullable=True)  # 图片URL（如果有的话）
    source = db.Column(db.String(20), default='scrape')  # scrape, upload
    is_favorite = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    last_synced = db.Column(db.DateTime, default=datetime.utcnow)
    
    def to_dict(self):
        """转换为字典格式，用于API响应"""
        # 处理缩略图路径，如果是本地文件路径，转换为URL
        image_url = self.image_data
        if image_url and not image_url.startswith(('http://', 'https://', 'data:')):
            # 如果是本地文件路径，转换为API URL
            filename = os.path.basename(image_url)
            image_url = f'/api/files/{filename}'
        
        # 处理原图路径，如果是本地文件路径，转换为URL
        original_url = self.original_image
        if original_url and not original_url.startswith(('http://', 'https://')):
            # 如果是本地文件路径，转换为API URL
            filename = os.path.basename(original_url)
            original_url = f'/api/files/original_images/{filename}'
        
        return {
            'id': self.id,
            'chrome_id': self.chrome_id,
            'text': self.text,
            'image_data': image_url,
            'original_image': original_url,
            'image_url': self.image_url,
            'source': self.source,
            'is_favorite': self.is_favorite,
            'created_at': (self.created_at.isoformat() + 'Z') if self.created_at else None,
            'updated_at': (self.updated_at.isoformat() + 'Z') if self.updated_at else None,
            'last_synced': (self.last_synced.isoformat() + 'Z') if self.last_synced else None
        }
    
    def from_chrome_data(self, chrome_data):
        """从Chrome插件数据创建或更新记录"""
        self.chrome_id = str(chrome_data.get('id') or chrome_data.get('chrome_id', ''))
        self.text = chrome_data.get('text', '')
        
        # 处理缩略图数据 - 支持多种字段名
        image_data = chrome_data.get('image') or chrome_data.get('image_data', '')
        if image_data and image_data.startswith('data:image'):
            # 如果是Base64图片数据，保存为文件
            self.image_data = self._save_image_to_file(image_data, self.chrome_id)
        else:
            self.image_data = image_data  # 可能是文件路径或URL
        
        # 处理原图数据 - 支持多种字段名
        original_image = chrome_data.get('originalImage') or chrome_data.get('original_image', '')
        if original_image:
            self.original_image = self._process_original_image(original_image, self.chrome_id)
        else:
            self.original_image = original_image
        
        self.source = chrome_data.get('source', 'scrape')
        # 处理字段名映射：Chrome插件使用isFavorite，数据库使用is_favorite
        self.is_favorite = chrome_data.get('isFavorite', chrome_data.get('is_favorite', False))
        self.last_synced = datetime.utcnow()
        
        # 如果是新记录，设置创建时间
        if not self.created_at:
            self.created_at = datetime.utcnow()
        
        # 更新修改时间
        self.updated_at = datetime.utcnow()
    
    def _save_image_to_file(self, image_data, chrome_id):
        """将Base64图片数据保存为文件，返回文件路径"""
        try:
            # 解析Base64数据
            if ',' in image_data:
                header, data = image_data.split(',', 1)
                # 获取图片格式
                if 'png' in header:
                    ext = 'png'
                elif 'jpeg' in header or 'jpg' in header:
                    ext = 'jpg'
                elif 'gif' in header:
                    ext = 'gif'
                elif 'webp' in header:
                    ext = 'webp'
                else:
                    ext = 'png'  # 默认PNG
            else:
                data = image_data
                ext = 'png'
            
            # 创建文件名
            filename = f"{chrome_id}_thumb.{ext}"
            filepath = os.path.join('files', filename)
            
            # 确保files目录存在
            os.makedirs('files', exist_ok=True)
            
            # 保存文件
            with open(filepath, 'wb') as f:
                f.write(base64.b64decode(data))
            
            return filepath
            
        except Exception as e:
            print(f"保存图片文件失败: {e}")
            return None
    
    def _save_original_image_to_file(self, image_data, chrome_id):
        """将Base64原图数据保存为文件，返回文件路径"""
        try:
            # 解析Base64数据
            if ',' in image_data:
                header, data = image_data.split(',', 1)
                # 获取图片格式
                if 'png' in header:
                    ext = 'png'
                elif 'jpeg' in header or 'jpg' in header:
                    ext = 'jpg'
                elif 'gif' in header:
                    ext = 'gif'
                elif 'webp' in header:
                    ext = 'webp'
                else:
                    ext = 'png'  # 默认PNG
            else:
                data = image_data
                ext = 'png'
            
            # 确保目录存在
            os.makedirs('files/original_images', exist_ok=True)
            
            # 创建文件名
            filename = f"{chrome_id}_original.{ext}"
            filepath = os.path.join('files', 'original_images', filename)
            
            # 保存文件
            with open(filepath, 'wb') as f:
                f.write(base64.b64decode(data))
            
            print(f"原图保存成功: {filepath}")
            return filepath
            
        except Exception as e:
            print(f"保存原图文件失败: {e}")
            return None
    
    def _process_original_image(self, original_image, chrome_id):
        """处理原图数据，返回文件路径或URL"""
        try:
            # 如果是Base64数据，保存为文件
            if original_image.startswith('data:image'):
                print(f"处理Base64原图数据 (Chrome ID: {chrome_id})")
                return self._save_original_image_to_file(original_image, chrome_id)
            
            # 如果是网络URL，下载到本地
            if original_image.startswith(('http://', 'https://')):
                return self._download_original_image(original_image, chrome_id)
            
            # 如果是本地路径，直接返回
            if os.path.exists(original_image) or original_image.startswith(('files/', './', '../')):
                return original_image
            
            # 其他情况，返回原值
            return original_image
            
        except Exception as e:
            print(f"处理原图失败: {e}")
            return None
    
    def _download_original_image(self, url, chrome_id):
        """下载网络图片到本地"""
        try:
            # 解析URL获取文件扩展名
            parsed_url = urllib.parse.urlparse(url)
            path = parsed_url.path
            ext = os.path.splitext(path)[1]
            if not ext:
                ext = '.jpg'  # 默认扩展名
            
            # 创建文件名
            filename = f"{chrome_id}_original{ext}"
            filepath = os.path.join('files', 'original_images', filename)
            
            # 确保目录存在
            os.makedirs(os.path.dirname(filepath), exist_ok=True)
            
            # 下载图片
            response = requests.get(url, timeout=30)
            response.raise_for_status()
            
            # 保存文件
            with open(filepath, 'wb') as f:
                f.write(response.content)
            
            print(f"下载原图成功: {url} -> {filepath}")
            return filepath
            
        except Exception as e:
            print(f"下载原图失败 {url}: {e}")
            return None
    
    @staticmethod
    def get_by_chrome_id(chrome_id):
        """根据Chrome ID查找记录"""
        return Prompt.query.filter_by(chrome_id=str(chrome_id)).first()
    
    @staticmethod
    def get_favorites():
        """获取所有收藏的提示词"""
        return Prompt.query.filter_by(is_favorite=True).order_by(Prompt.updated_at.desc()).all()
    
    @staticmethod
    def search_prompts(query, favorites_only=False):
        """搜索提示词"""
        base_query = Prompt.query
        
        if favorites_only:
            base_query = base_query.filter_by(is_favorite=True)
        
        if query:
            base_query = base_query.filter(Prompt.text.contains(query))
        
        return base_query.order_by(Prompt.updated_at.desc()).all()
    
    def __repr__(self):
        return f'<Prompt {self.chrome_id}: {self.text[:50]}...>'
